package com.prizedraw.prize_draw.controller;


import cn.hutool.core.convert.impl.ArrayConverter;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.prizedraw.prize_draw.common.lang.Result;
import com.prizedraw.prize_draw.entity.DepartmentRole;
import com.prizedraw.prize_draw.entity.SysRole;
import com.prizedraw.prize_draw.entity.SysUserRole;
import com.prizedraw.prize_draw.entity.UserDepartmentRole;
import com.prizedraw.prize_draw.mapper.DepartmentRoleMapper;
import com.prizedraw.prize_draw.service.DepartmentRoleService;
import com.prizedraw.prize_draw.service.UserDepartmentRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 *    打死岗位对部门一定是一对一，再也不给它们关联表，冗余就冗余一点，降到第二范式
 *    这样子就直接操作岗位信息，没有关联这，关联那的那么麻烦，复杂，可以直接对其单表操作！！！ymj
 *
 *
 *    为了三表，当操作关联表时，如果任何一个岗位没有与任何一个部门之间进行关联，我觉得该岗位就没有用，就像将其没有关联任何部门的岗位进行删除
 *    添加关联时，需判断是否已存在该岗位，没有则将其添加后，将添加后返回的id与部门进行关联，判断是否重复关联，只需判断是否出现部门id和岗位id相同的记录即可
 *    删除关联时，则需判断是否该部门岗位有存在员工，为了防止一个员工不属于任何一个部门或者是误删岗位，然后判断要删除的关联id的某岗位id数量是否等于关联
 *    某岗位id总数量相同，如果相同就代表删除之后，该岗位就是没有关联任何部门，则将其在岗位表中进行删除
 *    修改关联时，不确定是否有进行修改关联，添加的方式，然后到最后进行判断该关联表中是否含有该岗位id的关联，有则代表还有部门与该岗位相关联，不删除
 *    相反，没有就将其删除该岗位，因为是没有关联任何部门的岗位
 *    --因为是采用关联表一对一的操作来处理岗位表对部门表多对多的关系，且，明显可以分为三个管理操作，部门，岗位，关联关系，这样子就不用额外考虑岗位表的新增，删除操作
 *
 *    如果不将其没有关联任何部门的岗位进行删除，可能会更容易，不用判断是否没有关联则进行删除操作，且后续如果发现岗位表里有名称一样的可以继续使用，
 * </p>
 *
 * @author czj666
 * @since 2021-09-07
 */
@RestController
@RequestMapping("/department/role")
public class DepartmentRoleController extends BaseController {
    /*
     * 可以加个属性，1 部门的人数，2 部门岗位的人数，3 对部门岗位直接指定有哪些人
     * */

    @Autowired
    DepartmentRoleService departmentRoleService;

    @Autowired
    UserDepartmentRoleService userDepartmentRoleService;

    @Autowired
    DepartmentRoleMapper departmentRoleMapper;

    @PreAuthorize("hasAuthority('sys:role:list')")
    @GetMapping("/list")
    public Result list(String name){
        // 查询到对应名称的岗位id
        List<SysRole> sysRoles = sysRoleService.list(new QueryWrapper<SysRole>().like(StrUtil.isNotBlank(name), "name", name));
        List<Integer> sysRoleIds = sysRoles.stream().map(sysRole -> sysRole.getId()).collect(Collectors.toList());
        // 在关联表中分页查询出所有的部门岗位对象
        Page<DepartmentRole> pageDate = departmentRoleService.page(getPage(),
                new QueryWrapper<DepartmentRole>().in(sysRoleIds.size()>0,"role_id",sysRoleIds));
        pageDate.getRecords().forEach(dr -> {
            dr.setDepartment(departmentService.getById(dr.getDepartmentId()));
            dr.setSysRole(sysRoleService.getById(dr.getRoleId()));
        });
        return Result.succ(pageDate);
    }

    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result save(@RequestBody DepartmentRole departmentRole){
        SysRole sysRole = sysRoleService.getOne(new QueryWrapper<SysRole>().eq("name",departmentRole.getSysRole().getName()));
        // 岗位表中已存在该名称的岗位
        if (sysRole != null){
            departmentRole.setRoleId(sysRole.getId());
            // 判断是否重复岗位
            int count = departmentRoleService.count(new QueryWrapper<DepartmentRole>()
                    .eq("department_id", departmentRole.getDepartmentId())
                    .eq("role_id", departmentRole.getRoleId()));
            if (count > 0){
                return Result.fail("该部门岗位已存在");
            }
        }else {
            // 不存在则进行添加后返回id再进行添加到关联表
            sysRoleService.save(departmentRole.getSysRole());
            departmentRole.setRoleId(departmentRole.getSysRole().getId());
        }


        // 保存部门id和岗位id之间的关联关系
        departmentRoleService.save(departmentRole);
        return Result.succ("");
    }

    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    public Result update(@RequestBody DepartmentRole departmentRole){
        // 先保存，等待修改部门与岗位之间进行关联之后，看看还有没有与这个岗位关联的，没有则进行删除
        int oldRoleId = departmentRole.getRoleId();

        SysRole sysRole = sysRoleService.getOne(new QueryWrapper<SysRole>().eq("name",departmentRole.getSysRole().getName()));
        if (sysRole == null){
            // 岗位不存在则进行添加后返回id再进行添加到关联表，不存在，就一定不会出现重复问题
            sysRoleService.save(departmentRole.getSysRole());
            departmentRole.setRoleId(departmentRole.getSysRole().getId());
        }else if (departmentRole.getRoleId() == sysRole.getId() && departmentRole.getDepartmentId() == departmentRole.getDepartment().getId()){
            // 岗位存在，且没有变动关联关系
            departmentRoleService.updateById(departmentRole);
            return Result.succ("");
        } else {
            // 岗位存在，且变动了部门-岗位的变动关系
            departmentRole.setRoleId(sysRole.getId());
            // 判断是否重复岗位
            int count = departmentRoleService.count(new QueryWrapper<DepartmentRole>()
                    .eq("department_id", departmentRole.getDepartmentId())
                    .eq("role_id", departmentRole.getRoleId()));
            if (count > 0){
                return Result.fail("该部门岗位已存在");
            }
        }
        // 保存部门id和岗位id之间的关联关系
        departmentRoleService.updateById(departmentRole);
        // 如果修改后岗位id没有与任何部门进行关联，则进行删除该岗位
        if (departmentRoleService.count(new QueryWrapper<DepartmentRole>().eq("role_id",oldRoleId)) < 1){
            sysRoleService.removeById(oldRoleId);
        }
        return Result.succ("");
    }

    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    @Transactional
    public Result delete(@RequestBody Integer[] ids){
        int count = 0;
        for (Integer id : ids) {
            count = userDepartmentRoleService.count(new QueryWrapper<UserDepartmentRole>().eq("department_role_id", id));
            if (count > 0) {
                return Result.fail("请先设置当前岗位内员工到别的部门岗位");
            }
        }

        //查询将要删除的部门-岗位关联表中要被删除后没有与任何关联的岗位id
        List<Integer> sysRoleIds = departmentRoleMapper.getCountRoleIdEqByIds(ids);
        //删除部门-岗位表中的记录
        departmentRoleService.removeByIds(Arrays.asList(ids));
        //删除岗位表里没有任何关联部门的岗位
        sysRoleService.removeByIds(sysRoleIds);

        //删除员工-部门岗位记录   --上面设置了判断需把所有岗位内的员工移到别的岗位
//        userDepartmentRoleService.remove(new QueryWrapper<UserDepartmentRole>().in("department_role_id",ids));
        return Result.succ("");
    }
}
